-
Notifications
You must be signed in to change notification settings - Fork 329
Rails 8.1 support #2480
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Rails 8.1 support #2480
Conversation
f942020 to
e834b46
Compare
72a17f3 to
e4b0156
Compare
e4b0156 to
29a404c
Compare
|
Certainly. Dropped. |
43de9c7 to
e458c74
Compare
Add after_create callbacks to LOB module to handle CLOB/BLOB writing when using empty_clob()/empty_blob() placeholders in INSERT statements. Previously, the LOB module only had after_update callbacks, causing CLOB data to be lost when records were created with prepared_statements disabled (which generates SQL with empty_clob() literals instead of bind parameters). Changes: - Add before_create :record_lobs_for_create callback - Add after_create :enhanced_write_lobs callback - Add record_lobs_for_create method to track non-nil LOB columns on create - Add tests for CLOB creation with prepared_statements disabled This fixes the issue where CLOBs would be empty after creation in environments where prepared_statements defaults to false. Issue rsim#2477
Rails 8.1 removed the ExplainSubscriber class (commit f488878f1bc), causing test failures with: NameError: uninitialized constant ActiveRecord::ExplainSubscriber The ExplainSubscriber functionality was refactored into ExplainRegistry with lazy subscription - instead of subscribing at initialization, Rails 8.1 now subscribes only when .explain is first called via ExplainRegistry.start. The spec_helper.rb line that manually subscribed to ExplainSubscriber is no longer needed or valid. Rails 8.1 handles the subscription automatically and lazily. Related Rails commit: - f488878f1bc "Refactor ExplainRegistry to only be subscribed once used" - Author: Jean Boussier - Date: Thu Sep 25 10:37:09 2025 +0200 - Link: rails/rails@f488878
Switch from pre-release alpha constraint to stable release constraint for ActiveRecord 8.1.0 dependency, following Rails 8.1 stable release.
Document Rails 8.1 support with installation instructions, including the gem version constraint for activerecord-oracle_enhanced-adapter 8.1.
Add ability to write LOB data to tables that don't have a primary key by: 1. Exposing cursor.rowid method in OCI connection wrapper 2. Capturing ROWID after INSERT in exec_insert (@last_insert_rowid) 3. Using ROWID in write_lobs WHERE clause when no PK is available 4. Supporting composite primary keys (Array) in write_lobs The ROWID approach works because: - Ruby-oci8's cursor.rowid returns the ROWID of the last inserted row - ROWID uniquely identifies any row regardless of table structure - The after_create callback fires immediately after INSERT on same connection Also includes ORA-01741 diagnostic logging for empty column detection.
e458c74 to
e3e858a
Compare
|
Better. Rather than dropping, I just rebased this on top of master again. Since those commits were from earlier. |
|
Amazing work @andynu! I just want to point your attention also to #2483 as a big improvement of performance and memory usage for workloads involving LOBs. Basically I remove this |
…ents This spec clearly demonstrates the critical difference between LOB handling with prepared statements (bind parameters) vs without (raw SQL with empty_clob()). Key points demonstrated: - With prepared_statements: true, LOB data flows through type_cast() which creates OCI8::CLOB temp LOBs. Data is populated BEFORE INSERT. - With prepared_statements: false, SQL contains empty_clob() literals. The write_lobs callback is REQUIRED to populate LOB data after INSERT. This test suite will FAIL if the lob.rb callbacks are removed, proving they are necessary for backwards compatibility with prepared_statements: false. Related to: rsim#2483
When prepared_statements is enabled (the default), LOB data is already written during INSERT via temporary LOB binding in type_cast(). The write_lobs callback was redundantly writing the same data again via SELECT FOR UPDATE. This change skips the callback in the prepared statements path while preserving it for the unprepared path, where empty_clob()/empty_blob() literals require the callback to populate LOB data after INSERT. Fixes the double-write issue identified in rsim#2483.
| # After setting large objects to empty, select the OCI8::LOB | ||
| # and write back the data. | ||
| before_create :record_lobs_for_create | ||
| after_create :enhanced_write_lobs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For create, shouldn't it just write all non-empty and non-null lobs instead of tracking them?
But anyway, I think this LOB callback writing stuff needs to go unless there are non-easily adaptable use-cases for disabling prepared statements as discussed in #2483
P.S. adding this here, doesn't it mean write_lobs was not used for a long time on create already? And that people just use prepared statements and don't need this?
This PR brings full Rails 8.1 compatibility to the Oracle Enhanced adapter, building on excellent work by @akostadinov (Aleksandar N. Kostadinov) in PR #2471.
I've added only two additional fixes:
Credits
The vast majority of this work was done by Aleksandar N. Kostadinov (@akostadinov) and Daria Mayorova (@mayorova). Their comprehensive compatibility updates fixed nearly all Rails 8.1 issues.
Changes from @akostadinov's PR #2471
Core Rails 8.1 API Compatibility
constructors
Test Infrastructure & Coverage
My Contributions (this PR)
CLOB Insertion Fix
prepared_statements: false(which happens when config.active_record.query_log_tags_enabled = true) #2477Rails 8.1 ExplainSubscriber Removal
(rails/rails@f488878)
Testing
All tests pass against Rails 8.1 (8-1-stable branch).